﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using TransportLayer;

namespace TransportLayer.ExecNode
{
    public partial class SourceForm : Form
    {
        private NodeLibrary.Source source;
        private NodeLibrary.Caller caller;
        private Thread refresher;
        private bool refloop = true;

        public SourceForm(TransportLayer.Node cNode, int mPort)
        {
            source = new NodeLibrary.Source(cNode, mPort);
            caller = new NodeLibrary.Caller(source.Id,source.Name);
            source.CallerListeningPort = caller.Port;
            InitializeComponent();
            refresher = new Thread(RefreshContent);
            refresher.Start();
            this.Text = cNode.Name;
            source.Snp.windowHideHandler += new NodeLibrary.WindowHideHandler(Hide);
            source.Snp.windowShowHandler += new NodeLibrary.WindowShowHandler(Show);
            speedTrackBar.Maximum = 10000;
            speedTrackBar.Minimum = 0;
            speedTrackBar.LargeChange = 1000;
            speedTrackBar.SmallChange = 1000;
                      
        }
        private void RefreshContent()
        {
            while (refloop)
            {
                Thread.Sleep(50);
                callerMessageTextBox.Text = caller.Message;
            }
        }
        private void sendButton_Click(object sender, EventArgs e)
        {

            NodeLibrary.CallerConnection connection = connectionComboBox.SelectedItem as NodeLibrary.CallerConnection;
                
            if (source.Matrix.ContainsKey(connection.CallId) && messageTextBox.Text != "")
            {
                source.Speed = speedTrackBar.Value;
                NodeLibrary.PduStream pduStream = AddTarget(connection);

                source.Message = messageTextBox.Text;
                Thread send = new Thread(this.Send);
                send.Start(pduStream);
            }
        }

        private void Send(object data)
        {
            source.Send(data as NodeLibrary.PduStream);
        
        }


        private NodeLibrary.PduStream AddTarget(NodeLibrary.CallerConnection connection)
        {
            NodeLibrary.PduStream pduStream;
            if (!source.Targets.ContainsKey(connection.CallId))
            {
                pduStream = new NodeLibrary.PduStream(connection.CallId, speedTrackBar.Value, connection.Size, messageTextBox.Text);
                source.Targets.Add(connection.CallId, pduStream);
            }
            else
            {
                pduStream = source.Targets[connection.CallId];
                pduStream.Message = messageTextBox.Text;
                pduStream.Capacity = speedTrackBar.Value;
            }
            return pduStream;
        
        }

        private void connectButton_Click(object sender, EventArgs e)
        {
            caller.BeginCall(targetTextBox.Text, Convert.ToInt32(capNumeric.Value));
        }

        private void SourceForm_Load(object sender, EventArgs e)
        {

        }

        private void refreshButton_Click(object sender, EventArgs e)
        {
           
                for (int i = connectionComboBox.Items.Count; i < caller.ReadyConnections.Count; ++i)
                    connectionComboBox.Items.Add(caller.ReadyConnections[i]);

        }

        private void SourceForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            refloop = false;
            source.Clean();
            caller.Clean();
        }

        private void logButton_Click(object sender, EventArgs e)
        {
            LogGui log = new LogGui(source.Log);
            log.Show();
        }

        private void toolsButton_Click(object sender, EventArgs e)
        {
            ToolsGui tool = new ToolsGui();
            tool.Show();
        }


        private void speedTrackBar_ValueChanged(object sender, EventArgs e)
        {
            if (connectionComboBox.Items.Count > 0)
            {
                NodeLibrary.CallerConnection connection = connectionComboBox.SelectedItem as NodeLibrary.CallerConnection;
                NodeLibrary.PduStream pdu = AddTarget(connection);
                speedTrackBar.Maximum = pdu.CapacityMax;
                source.Speed = speedTrackBar.Value;
                speedlabel.Text = "" + speedTrackBar.Value;
                pdu.Capacity = speedTrackBar.Value;
            }
        }

        private void ConnectionsListBox_MouseClick(object sender, MouseEventArgs e)
        {

        }

        private void hideButton_Click(object sender, EventArgs e)
        {
            this.Hide();
        }

        private void connectionComboBox_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (connectionComboBox.Items.Count > 0)
            {
                NodeLibrary.CallerConnection connection = connectionComboBox.SelectedItem as NodeLibrary.CallerConnection;
                NodeLibrary.PduStream pdu = AddTarget(connection);
                speedTrackBar.Maximum = pdu.CapacityMax;
                speedTrackBar.Value = pdu.Capacity;
            }
        }

        private void teardownButton_Click(object sender, EventArgs e)
        {
            NodeLibrary.CallerConnection connection = connectionComboBox.SelectedItem as NodeLibrary.CallerConnection;
            caller.ByeConnection(connection);
        }

        private void senddButton2_Click(object sender, EventArgs e)
        {
            NodeLibrary.CallerConnection connection = connectionComboBox.SelectedItem as NodeLibrary.CallerConnection;

            if (source.Matrix.ContainsKey(connection.CallId) && messageTextBox.Text != "")
            {
                source.Speed = speedTrackBar.Value;
                NodeLibrary.PduStream pduStream = AddTarget(connection);

                source.Message = messageTextBox.Text;
                Thread send = new Thread(this.Send);
                send.Start(pduStream);
            }
        }

    }
}
